﻿// -----------------------------------------------------------------------
// <copyright file="PersonInformationService.cs" company="EPAM Systems">
////Copyright (c) EPAM Systems, 2012. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

namespace MBOP.Domain.Services
{
	#region Usings

	using System;
	using System.Collections.Generic;

	using MBOP.Core.DTO;
	using MBOP.Core.Entities.Common;
	using MBOP.Core.Interfaces.DataProviders;
	using MBOP.Core.Interfaces.Managers;
	using MBOP.Core.Interfaces.Services;
	using MBOP.Helpers.Extensions;

	#endregion

	/// <summary>
	/// The <see cref="IPersonInformationService"/> implementer
	/// which handles person's operations.
	/// </summary>
	public class PersonInformationService : IPersonInformationService
	{
		#region Constants

		/// <summary>
		/// Represents the location string.
		/// </summary>
		private const string CITY_LOCATION_FILTER = "Mogilev";

		#endregion

		#region Private Fields

		/// <summary>
		/// Represents the cache manager.
		/// </summary>
		private ICacheManager _cacheManager;

		/// <summary>
		/// Represents the active directory data provider.
		/// </summary>
		private IActiveDirectoryDataProvider _activeDirectoryDataProvider;

		#endregion

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="PersonInformationService"/> class.
		/// </summary>
		/// <param name="activeDirectoryDataProvider">The <see cref="IActiveDirectoryDataProvider"/> implementer</param>
		/// <param name="cacheManager">The <see cref="ICacheManager"/> implementer</param>
		public PersonInformationService(IActiveDirectoryDataProvider activeDirectoryDataProvider, ICacheManager cacheManager)
		{
			this._activeDirectoryDataProvider = activeDirectoryDataProvider;
			this._cacheManager = cacheManager;
		}

		#endregion

		#region IPersonInformationService Members

		#region Methods

		/// <summary>
		/// Gets the person info.
		/// </summary>
		/// <param name="personFindingInfo">The person finding info.</param>
		/// <param name="findingType">The finding type.</param>
		/// <param name="isImageInclude">Indicates image including.</param>
		/// <returns>The person info.</returns>
		public PersonInfo GetPersonInfo(string personFindingInfo, PersonFindingType findingType, bool isImageInclude)
		{
			PersonInfo personInfo = null;

			if (IsCorrectFindingInfo(personFindingInfo, findingType))
			{
				if (findingType == PersonFindingType.ID && this._cacheManager.IsInCache(personFindingInfo))
				{
					personInfo = this._cacheManager.GetItem<PersonInfo>(personFindingInfo);
				}
				else
				{
					personInfo = this._activeDirectoryDataProvider.GetPersonInfo(personFindingInfo, findingType, isImageInclude);

					if (findingType == PersonFindingType.ID)
					{
						this._cacheManager.Add(personFindingInfo, personInfo, true);
					}
				}

				if (isImageInclude)
				{
					if (personInfo.Photo == null)
					{
						personInfo.Photo = this._activeDirectoryDataProvider.GetPersonInfo(personFindingInfo, findingType, true).Photo;
					}

					if (personInfo.Photo != null)
					{
						this._cacheManager.Add(personInfo.Photo.ID, personInfo.Photo, true, TimeSpan.FromMinutes(1));
					}
				}
			}

			return personInfo;
		}

		/// <summary>
		/// Gets the person list specified by begin name sequence.
		/// </summary>
		/// <param name="nameSequence">The begin name sequence.</param>
		/// <param name="isRestricted">The location restricted indicator.</param>
		/// <returns>The person list.</returns>
		public IEnumerable<PersonInfo> GetPersonList(string nameSequence, bool isRestricted)
		{
			IEnumerable<PersonInfo> personList = new List<PersonInfo>();

			if (!string.IsNullOrEmpty(nameSequence))
			{
				personList = this._activeDirectoryDataProvider.GetPersonList(nameSequence, isRestricted);
			}

			return personList;
		}

		#endregion

		#endregion

		#region Private Methods

		/// <summary>
		/// Checks the current finding info is correct or not.
		/// </summary>
		/// <param name="personFindingInfo">The finding info.</param>
		/// <param name="findingType">The info finding type.</param>
		/// <returns>The result of checking operation.</returns>
		private static bool IsCorrectFindingInfo(string personFindingInfo, PersonFindingType findingType)
		{
			bool isCorrectFindingInfo = personFindingInfo != null;

			if (findingType == PersonFindingType.ID)
			{
				Guid id;

				if (!Guid.TryParse(personFindingInfo, out id))
				{
					isCorrectFindingInfo = false;
				}
			}

			return isCorrectFindingInfo;
		}

		#endregion
	}
}
